
#include <BHBoxLayout>
#include <BVBoxLayout>
#include <BRoundHandler>
#include <BListItem>

#include "TerrainPanel.h"
#include "MainWindow.h"

MainWindow::MainWindow()
{
	_convertDialog = new ConvertDialog(this);
	_carverDialog = new CarverDialog(this);
	_painterDialog = new PainterDialog(this);
	_terrainCreater = new TerrainCreater();

	BHBoxLayout* toolbarLayout = new BHBoxLayout();
	{
		_menuBar = new BMenuBar();
		{
			_fileMenu = new BMenu("File");
			_fileMenu->addAction("New");
			_fileMenu->addAction("Save");
			_fileMenu->addAction("Open");
			_menuBar->addMenu(_fileMenu);
		}
		_convertButton = new BButton("Convert");
		_carverButton = new BButton("Carver");
		_paintButton = new BButton("Paint");
		_lightingCheckBox = new BCheckBox("lighting");
		_lightingCheckBox->setChecked(true);
		_polygonLineCheckBox = new BCheckBox("polygon line");

		toolbarLayout->addWidget(_menuBar);
		toolbarLayout->addWidget(_convertButton);
		toolbarLayout->addWidget(_carverButton);
		toolbarLayout->addWidget(_paintButton);
		toolbarLayout->addWidget(_lightingCheckBox);
		toolbarLayout->addWidget(_polygonLineCheckBox);
		toolbarLayout->addSpring();
	}

	BHBoxLayout* splitLayout = new BHBoxLayout();
	splitLayout->setSplitable(true);
	splitLayout->setSpacing(6);
	{
		BVBoxLayout* leftLayout = new BVBoxLayout();
		{
			_objectListWidget = new BListWidget();
			_objectListWidget->setAreaPolicy(Policy_Preferred | Policy_Dynamic);
			_targetLayout = new BVBoxLayout();
			leftLayout->addWidget(_objectListWidget);
			leftLayout->addLayout(_targetLayout);
		}
		_viewer = new BViewer();
		{
			BScene* scene = new BScene();
			BCamera* camera = new BCamera();
			camera->setColor(30, 30, 30);
			_mainHandler = new BRoundHandler();

			_viewer->setScene(scene);
			_viewer->setCamera(camera);
			_viewer->setHandler(_mainHandler);
		}

		splitLayout->addLayout(leftLayout);
		splitLayout->addWidget(_viewer, 5);
	}

	BVBoxLayout* vlayout = new BVBoxLayout(this);
	vlayout->addLayout(toolbarLayout, 0);
	vlayout->addLayout(splitLayout);

	connect(_fileMenu, Signal_Triggered, &MainWindow::slotMenuTriggered);
	connect(_convertButton, Signal_Clicked, &MainWindow::slotConvertButtonClicked);
	connect(_carverButton, Signal_Clicked, &MainWindow::slotCarverButtonClicked);
	connect(_paintButton, Signal_Clicked, &MainWindow::slotPaintButtonClicked);
	connect(_lightingCheckBox, Signal_Checked, &MainWindow::slotLightingChecked);
	connect(_polygonLineCheckBox, Signal_Checked, &MainWindow::slotPolygonLineChecked);
	connect(_objectListWidget, Signal_Clicked, &MainWindow::slotListClicked);

	connect(_terrainCreater, "finished", &MainWindow::slotTerrainCreateFinished);
	connect("target", &MainWindow::slotTargetChanged);
	connect("apply-handler", &MainWindow::slotApplyHandler);

}
MainWindow::~MainWindow()
{

}

void MainWindow::loadTerrain(const BString& fileName)
{
	if (fileName.empty())
		return;
	if (BTerrain* terrain = ConvertDialog::CreateTerrain(fileName))
	{
		_viewer->scene()->insert(terrain);
		_mainHandler->focus();

		BListItem* item = _objectListWidget->addItem(fileName.name());
		item->setForm(Form_TextUnderIcon);
		item->setAlign(Align_Center);
		item->setIconSize(100);
		item->setAsset(terrain);
		if (BImage* image = dynamic_cast<BImage*>(terrain->texture()))
		{
			item->setImage(image);
		}
	}
}

void MainWindow::slotTargetChanged(BObject* object, const BValue& value)
{
	if (_targetLayout->asset() != value)
	{
		for (int i = 0; i < _targetLayout->count(); i++)
		{
			BWidget* widget = _targetLayout->widget(i);
			this->removeChild(widget);
		}
		_targetLayout->clear();
		_targetLayout->setAsset(value);
		if (BTerrain* terrain = value)
		{
			TerrainPanel* terrainPanel = new TerrainPanel();
			_targetLayout->addWidget(terrainPanel);
		}
		_targetLayout->addSpring();
	}
}
void MainWindow::slotMenuTriggered(BObject* object, const BValue& value)
{
	BAction* action = value;
	if (action->text() == "Ground")
	{
		
	}
}
void MainWindow::slotConvertButtonClicked()
{
	_convertDialog->popup();
}
void MainWindow::slotCarverButtonClicked()
{
	BTerrain* terrain = 0;
	BScene* scene = _viewer->scene();
	for (int i = 0; i < scene->shapeCount(); i++)
	{
		BShape* shape = scene->shape(i);
		terrain = dynamic_cast<BTerrain*>(shape);
		if (terrain)
			break;
	}
	_carverDialog->setTerrain(terrain);
	_carverDialog->popup();
}
void MainWindow::slotPaintButtonClicked()
{
	BTerrain* terrain = 0;
	BScene* scene = _viewer->scene();
	for (int i = 0; i < scene->shapeCount(); i++)
	{
		BShape* shape = scene->shape(i);
		terrain = dynamic_cast<BTerrain*>(shape);
		if (terrain)
			break;
	}
	_painterDialog->setTerrain(terrain);
	_painterDialog->popup();
}
void MainWindow::slotLightingChecked(BObject* object, const BValue& value)
{
	bool lighting = value;
	BScene* scene = _viewer->scene();
	for (int i = 0; i < scene->shapeCount(); i++)
	{
		BShape* shape = scene->shape(i);
		shape->setLighting(lighting);
	}
}
void MainWindow::slotPolygonLineChecked(BObject* object, const BValue& value)
{
	PolyMode pmode = Poly_Fill;
	if (value == true)
		pmode = Poly_Line;
	BScene* scene = _viewer->scene();
	for (int i = 0; i < scene->shapeCount(); i++)
	{
		BShape* shape = scene->shape(i);
		shape->setPolyMode(pmode);
	}
}
void MainWindow::slotListClicked(BObject* object, const BValue& value)
{
	BListWidget* listWidget = (BListWidget*)object;
	if (BListItem* item = listWidget->selectedItem())
		emit("target", item->asset());
	else
		emit("target");
}
void MainWindow::slotApplyHandler(BObject* object, const BValue& value)
{
	BHandler* handler = value;
	if (handler)
	{
		_mainHandler->addChild(handler);
		connect(handler, Signal_Detached, &MainWindow::slotHandlerDetached);
	}
	else
	{
		_viewer->setHandler(_mainHandler);
	}
}
void MainWindow::slotHandlerDetached(BObject* object, const BValue& value)
{
	if (BHandler* handler = value)
	{
		disconnect(handler);
		_viewer->setHandler(_mainHandler);
	}
}
void MainWindow::slotTerrainCreateFinished(BObject* object, const BValue& value)
{

}
